DIP-Introductory python tutorials for image processing(48-50)-Image Quality

学习自 Youtube 博主 DigitalSreeni。

正文

Tutorial 48 - Image quality metrics using a reference image - in python

Common metrics to quantify image quality(reference based) 量化图像质量的常用度量

  • Mean squared error(MSE), MSE=1nΣ(yy^)2MSE=\frac{1}{n}\Sigma(y-\hat{y})^2(The square of the difference between actual and predicted)

  • Root mean squared error(RMSE) - Square root of MSE

  • Peak signal to noise ratio(PSNR), PSNR=10log10(MAXI2MSE)PSNR=10\cdot \log_{10}\left(\frac{MAX_I^2}{MSE}\right)(MAX is the maximum pixel value for 8 bit image, it is 255)

  • SSI: Takes texture into account.

python
import cv2
import numpy as np
from sewar import full_ref
from skimage import metrics
 
ref_img = cv2.imread("images/sandstone.tif", 1)
img = cv2.imread("images/sandstone_blur_2sigma.tif", 1)
python
mse_skimg = metrics.mean_squared_error(ref_img, img)
print("MSE: based on scikit-image = ", mse_skimg)
MSE: based on scikit-image =  170.83926291047953
python
psnr_skimg = metrics.peak_signal_noise_ratio(ref_img, img, data_range=None)
print("PSNR: based on scikit-image = ", psnr_skimg)
PSNR: based on scikit-image =  25.80492671881574
python
rmse_skimg = metrics.normalized_root_mse(ref_img, img)
print("RMSE: based on scikit-image = ", rmse_skimg)
RMSE: based on scikit-image =  0.10647019507436659
python
from skimage.metrics import structural_similarity as ssim
ssim_skimg = ssim(ref_img, img,
                  data_range = img.max() - img.min(), 
                  multichannel = True)
print("SSIM: based on scikit-image = ", ssim_skimg)
SSIM: based on scikit-image =  0.6631528566884437


C:\Users\gzjzx\AppData\Local\Temp\ipykernel_7180\3842229405.py:2: FutureWarning: `multichannel` is a deprecated argument name for `structural_similarity`. It will be removed in version 1.0. Please use `channel_axis` instead.
  ssim_skimg = ssim(ref_img, img,

如果两幅图片完全相同:

python
img = ref_img
python
mse_skimg = metrics.mean_squared_error(ref_img, img)
print("MSE: based on scikit-image = ", mse_skimg)
psnr_skimg = metrics.peak_signal_noise_ratio(ref_img, img, data_range=None)
print("PSNR: based on scikit-image = ", psnr_skimg)
rmse_skimg = metrics.normalized_root_mse(ref_img, img)
print("RMSE: based on scikit-image = ", rmse_skimg)
from skimage.metrics import structural_similarity as ssim
ssim_skimg = ssim(ref_img, img,
                  data_range = img.max() - img.min(), 
                  multichannel = True)
print("SSIM: based on scikit-image = ", ssim_skimg)
MSE: based on scikit-image =  0.0
PSNR: based on scikit-image =  inf
RMSE: based on scikit-image =  0.0
SSIM: based on scikit-image =  1.0


C:\Users\gzjzx\anaconda3\lib\site-packages\skimage\metrics\simple_metrics.py:163: RuntimeWarning: divide by zero encountered in double_scalars
  return 10 * np.log10((data_range ** 2) / err)
C:\Users\gzjzx\AppData\Local\Temp\ipykernel_7180\397432051.py:8: FutureWarning: `multichannel` is a deprecated argument name for `structural_similarity`. It will be removed in version 1.0. Please use `channel_axis` instead.
  ssim_skimg = ssim(ref_img, img,
python
ref_img = cv2.imread("images/sandstone.tif", 1)
img = cv2.imread("images/sandstone_blur_2sigma.tif", 1)
  • ERGAS Global relative error
python
"""
calculates global relative error 
 
GT: first (original) input image.
P: second (deformed) input image.
r: ratio of high resolution to low resolution (default=4).
ws: sliding window size (default = 8).
 
:returns:  float -- ergas value.
"""
ergas_img = full_ref.ergas(ref_img, img, r=4, ws=8)
print("EGRAS: global relative error = ", ergas_img)
EGRAS: global relative error =  5267.3334783814835
  • Multiscale structural similarity index
python
"""calculates multi-scale structural similarity index (ms-ssim).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
:param weights: weights for each scale (default = [0.0448, 0.2856, 0.3001, 0.2363, 0.1333]).
:param ws: sliding window size (default = 11).
:param K1: First constant for SSIM (default = 0.01).
:param K2: Second constant for SSIM (default = 0.03).
:param MAX: Maximum value of datarange (if None, MAX is calculated using image dtype).
 
:returns:  float -- ms-ssim value.
"""
msssim_img=full_ref.msssim(ref_img, img, weights=[0.0448, 0.2856, 0.3001, 0.2363, 0.1333], ws=11, K1=0.01, K2=0.03, MAX=None)
print("MSSSIM: multi-scale structural similarity index = ", msssim_img)
MSSSIM: multi-scale structural similarity index =  (0.8966196945619169+0j)
  • PSNR
python
"""calculates peak signal-to-noise ratio (psnr).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
:param MAX: maximum value of datarange (if None, MAX is calculated using image dtype).
 
:returns:  float -- psnr value in dB.
"""
psnr_img=full_ref.psnr(ref_img, img, MAX=None)
print("PSNR: peak signal-to-noise ratio = ", psnr_img)
PSNR: peak signal-to-noise ratio =  25.80492671881574
  • PSNRB: Calculates PSNR with Blocking Effect Factor for a given pair of images (PSNR-B)
python
"""Calculates PSNR with Blocking Effect Factor for a given pair of images (PSNR-B)
 
:param GT: first (original) input image in YCbCr format or Grayscale.
:param P: second (corrected) input image in YCbCr format or Grayscale.
 
:return: float -- psnr_b.
"""
psnrb_img = full_ref.psnrb(ref_img, img)
print("PSNRB: peak signal-to-noise ratio with blocking effect = ", psnrb_img)
PSNRB: peak signal-to-noise ratio with blocking effect =  25.80492671881574
  • relative average spectral error (rase)
python
"""calculates relative average spectral error (rase).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
:param ws: sliding window size (default = 8).
 
:returns:  float -- rase value.
"""
RASE_img = full_ref.rase(ref_img, img, ws=8)
print("RASE: relative average spectral error = ", RASE_img)
RASE: relative average spectral error =  760.2741004137694
  • RMSE
python
"""calculates root mean squared error (rmse).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
 
:returns:  float -- rmse value.
"""
rmse_img = full_ref.rmse(ref_img, img)
print("RMSE: root mean squared error = ", rmse_img)
RMSE: root mean squared error =  13.07054944944854
  • root mean squared error (rmse) using sliding window
python
"""calculates root mean squared error (rmse) using sliding window.
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
:param ws: sliding window size (default = 8).
 
:returns:  tuple -- rmse value,rmse map.	
"""
rmse_sw_img = full_ref.rmse_sw(ref_img, img, ws=8)
print("RMSE_SW: root mean squared error with sliding window = ", rmse_sw_img)
RMSE_SW: root mean squared error with sliding window =  (11.495024661505164, array([[[6.31466547, 6.31466547, 6.31466547],
        [6.34182545, 6.34182545, 6.34182545],
        [6.10327781, 6.10327781, 6.10327781],
        ...,
        [7.47704821, 7.47704821, 7.47704821],
        [7.13267131, 7.13267131, 7.13267131],
        [7.23057743, 7.23057743, 7.23057743]],

       [[5.84433486, 5.84433486, 5.84433486],
        [5.8255901 , 5.8255901 , 5.8255901 ],
        [5.52409495, 5.52409495, 5.52409495],
        ...,
        [8.14996166, 8.14996166, 8.14996166],
        [7.76912962, 7.76912962, 7.76912962],
        [7.94217382, 7.94217382, 7.94217382]],

       [[5.9187203 , 5.9187203 , 5.9187203 ],
        [5.84967948, 5.84967948, 5.84967948],
        [5.51701912, 5.51701912, 5.51701912],
        ...,
        [7.7741559 , 7.7741559 , 7.7741559 ],
        [7.49478986, 7.49478986, 7.49478986],
        [7.71463706, 7.71463706, 7.71463706]],

       ...,

       [[6.12627538, 6.12627538, 6.12627538],
        [5.84967948, 5.84967948, 5.84967948],
        [5.89623821, 5.89623821, 5.89623821],
        ...,
        [6.6602834 , 6.6602834 , 6.6602834 ],
        [6.55982088, 6.55982088, 6.55982088],
        [6.43234017, 6.43234017, 6.43234017]],

       [[5.92927061, 5.92927061, 5.92927061],
        [5.71319744, 5.71319744, 5.71319744],
        [5.8656841 , 5.8656841 , 5.8656841 ],
        ...,
        [6.66848933, 6.66848933, 6.66848933],
        [6.51800391, 6.51800391, 6.51800391],
        [6.27245965, 6.27245965, 6.27245965]],

       [[5.69539287, 5.69539287, 5.69539287],
        [5.48007755, 5.48007755, 5.48007755],
        [5.55512151, 5.55512151, 5.55512151],
        ...,
        [6.83053805, 6.83053805, 6.83053805],
        [6.63678198, 6.63678198, 6.63678198],
        [6.09559267, 6.09559267, 6.09559267]]]))
  • calculates spectral angle mapper (sam).
python
"""calculates spectral angle mapper (sam).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
 
:returns:  float -- sam value.
"""
ref_sam_img = full_ref.sam(ref_img, img)
print("REF_SAM: spectral angle mapper = ", ref_sam_img)
REF_SAM: spectral angle mapper =  0.106389325534101
  • Structural similarity index
python
"""calculates structural similarity index (ssim).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
:param ws: sliding window size (default = 8).
:param K1: First constant for SSIM (default = 0.01).
:param K2: Second constant for SSIM (default = 0.03).
:param MAX: Maximum value of datarange (if None, MAX is calculated using image dtype).
 
:returns:  tuple -- ssim value, cs value.
"""
ssim_img = full_ref.ssim(ref_img, img, ws=11, K1=0.01, K2=0.03, MAX=None, fltr_specs=None, mode='valid')
print("SSIM: structural similarity index = ", ssim_img)
SSIM: structural similarity index =  (0.7221593484301166, 0.7224356503602157)
  • Universal image quality index
python
"""calculates universal image quality index (uqi).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
:param ws: sliding window size (default = 8).
 
:returns:  float -- uqi value.
"""
UQI_img = full_ref.uqi(ref_img, img, ws=8)
print("UQI: universal image quality index = ", UQI_img)
UQI: universal image quality index =  0.9892148366610988
  • Pixel Based Visual Information Fidelity (vif-p)
python
"""calculates Pixel Based Visual Information Fidelity (vif-p).
 
:param GT: first (original) input image.
:param P: second (deformed) input image.
:param sigma_nsq: variance of the visual noise (default = 2)
 
:returns:  float -- vif-p value.
"""
VIFP_img = full_ref.vifp(ref_img, img, sigma_nsq=2)
print("VIFP: Pixel Based Visual Information Fidelity = ", VIFP_img)
VIFP: Pixel Based Visual Information Fidelity =  0.27836263237462544

Tutorial 49 - No reference based image quality estimation by quantifying sharpness

论文: Sharpness Estimation for Document and Scene Images

{% pdf Sharpness_Estimation_for_Document_and_Sc.pdf%}

Sharpness Estimation for Document and Scene Images

python
pip install -e.
Obtaining file:///C:/Users/gzjzx/Jupyter/DIP/pydom-master
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
Requirement already satisfied: numpy in c:\users\gzjzx\anaconda3\lib\site-packages (from pydom0.1) (1.23.1)
Requirement already satisfied: opencv-python in c:\users\gzjzx\anaconda3\lib\site-packages (from pydom0.1) (4.6.0.66)
Installing collected packages: pydom
  Running setup.py develop for pydom
Successfully installed pydom-0.1
Note: you may need to restart the kernel to use updated packages.
python
from dom import DOM
import cv2
 
img1 = cv2.imread("images/Osteosarcoma_01.tif", 1)
img2 = cv2.imread("images/Osteosarcoma_01_1sigma_blur.tif", 1)
img3 = cv2.imread("images/Osteosarcoma_01_2sigma_blur.tif", 1)
python
iqa = DOM()
  • 计算清晰度指数:
python
score1 = iqa.get_sharpness(img1)
score2 = iqa.get_sharpness(img2)
score3 = iqa.get_sharpness(img3)
 
print("Sharpness for reference image:", score1)
print("Sharpness for 1sigma blurred image:", score2)
print("Sharpness for 2sigma blurred image:", score3)
Sharpness for reference image: 0.720903262659802
Sharpness for 1sigma blurred image: 0.8156158621086446
Sharpness for 2sigma blurred image: 0.5502472959626157

Tutorial 50 - No reference based image quality using BRISQUE -in Python

{% pdf TIP_BRISQUE.pdf%}

  • BRISQUE calculates the no-reference image quality score for an image using the Blind/Referenceless Image Spatial Quality Evaluator(BRISQUE).
    • BRISQUE 使用盲/无参考图像空间质量评估器(BRISQUE)计算图像的无参考图像质量分数。
  • BRISQUE score is computed using a support vector regression (SVR) model trained on an image database with corresponding differential mean opinion score (DMOS) values.
    • BRISQUE 评分的计算使用支持向量回归(SVR)模型训练的图像数据库与相应的差分平均意见评分(DMOS)值。
  • The database contains images with known distortion such as compression artifacts, blurring, and noise.
    • 该数据库包含已知失真的图像,如压缩伪影、模糊和噪声。
  • The image to be scored must have at least one of the distortions for which th model was trained.
    • 要评分的图像必须至少有一个失真的模型训练。
python
pip install image-quality
python
import numpy as np
from skimage import io, img_as_float
import imquality.brisque as brisque

暂时跑不了..过段时间再解决?

python
#img = img_as_float(io.imread('noisy_images/BSE.jpg', as_gray=True))
img = img_as_float(io.imread('images/noisy_images/sandstone_25sigma_noisy.tif', as_gray=True))
 
score = brisque.score(img)
print("Brisque score = ", score)
 
# Now let us check BRISQUE scores for a few blurred images.
 
img0 = img_as_float(io.imread('images/blurred_images/sandstone.tif', as_gray=True))
img2 = img_as_float(io.imread('images/blurred_images/sandstone_2sigma_blur.tif', as_gray=True))
img3 = img_as_float(io.imread('images/blurred_images/sandstone_3sigma_blur.tif', as_gray=True))
img5 = img_as_float(io.imread('images/blurred_images/sandstone_5sigma_blur.tif', as_gray=True))
 
score0 = brisque.score(img0)
score2 = brisque.score(img2)
score3 = brisque.score(img3)
score5 = brisque.score(img5)
 
print("BRISQUE Score for 0 blur = ", score0)
print("BRISQUE Score for 2sigma blur = ", score2)
print("BRISQUE Score for 3sigma blur = ", score3)
print("BRISQUE Score for 5sigma blur = ", score5)
python
from skimage.metrics import peak_signal_noise_ratio
 
psnr_1 = peak_signal_noise_ratio(img0, img1)
psnr_2 = peak_signal_noise_ratio(img0, img2)
 
print("PSNR for 1sigma blur = ", psnr_1)
print("PSNR for 2sigma blur = ", psnr_2)
PSNR for 1sigma blur =  37.288893529075025
PSNR for 2sigma blur =  33.23605158876105